
#include "main.h"
#define PWM_PERIOD  (20000) //一般舵机的周期20ms

static const char *TAG = "pwm_back";

uint32_t duties[1] = {500};
const uint32_t pin_num[1] = { GPIO_NUM_14 };
float phase[1] = {0};

int minDu = 500; //0.5ms 0度
int maxDu = 2500; //2.5ms 180度
int chaDu = 2000;
int perDu = 11; //2000/180  一度换算成时间

int pwmOpen = 0;
int closePwm = 0;
int pwmLock = 0;

void initPwm(int du) 
{
    int us = minDu + du * perDu;
    ESP_LOGI(TAG, "initPwm %d", us);
    if (pwmOpen) {
        pwm_set_duty(0, us);
    } else {
        ESP_LOGI(TAG, "pwmOpen");
        duties[0] = us;
        pwm_init(PWM_PERIOD, duties, 1, pin_num);
        pwm_set_phases(phase);
        pwmOpen = 1;
    }
    pwm_start();
}

void closePwmHandle()
{
    vTaskDelay(500);  //5s之后，自动关闭pwm
    if (closePwm) {
        pwm_deinit();
        closePwm = 0; //允许再次关闭pwm
        pwmOpen = 0;
        printf("closePwm\n");
    }
    vTaskDelete(NULL);
}

void slide_callback(const blinker_widget_param_val_t *val)
{
    if (pwmLock) {
        ESP_LOGI(TAG, "pwmLock");
        return;
    }

    endSleep();

    pwmLock = 1; //占用pwm操作
    closePwm = 0; //禁止关闭pwm

    initPwm(val->i);

    pwmLock = 0; //1s之后，才允许其他的pwm操作
    closePwm = 1; //允许关闭pwm

    vTaskDelay(200);  //2s之后，自动关闭pwm
    if (closePwm) {
        pwm_deinit();
        closePwm = 0; //允许再次关闭pwm
        pwmOpen = 0;
        printf("closePwm\n");

        beginSleep();
    }
}

int openDu = 45;
int closeDu = 135;
int middleDu = 90;

void doLight(void* par){
    char* s = (char*) par;
    endSleep();

    pwmLock = 1; //占用pwm操作
    closePwm = 0; //禁止关闭pwm

    int du = 0;
    if (strcmp(s, "on") == 0) {
        du = openDu;
    } else {
        du = closeDu;
    }

    initPwm(du);
    vTaskDelay(100);
    initPwm(middleDu);

    pwmLock = 0; //1s之后，才允许其他的pwm操作
    closePwm = 1; //允许关闭pwm

    vTaskDelay(200);  //2s之后，自动关闭pwm
    if (closePwm) {
        pwm_deinit();
        closePwm = 0; //允许再次关闭pwm
        pwmOpen = 0;
        printf("closePwm\n");
        beginSleep();
    }

    vTaskDelete(NULL);
}

void light_callback(const blinker_widget_param_val_t *val)
{
    if (pwmLock) {
        ESP_LOGI(TAG, "pwmLock");
        return;
    }

    cJSON *param = cJSON_CreateObject();
    blinker_widget_switch(param, val->s);
    blinker_widget_print(BUTTON_LIGHT, param);
    cJSON_Delete(param);

    xTaskCreate(doLight, 
        "doLight",
        1024*2,
        ( void * )val->s,
        6,
        NULL);
}

void duer_callback(const blinker_va_param_cb_t *val)
{
    ESP_LOGI(TAG, "duer type %d", val->type);
    if (val->type != BLINKER_PARAM_POWER_STATE) {
        return;
    }
    if (pwmLock) {
        ESP_LOGI(TAG, "pwmLock");
        return;
    }
    
    cJSON *param = cJSON_CreateObject();
    blinker_dueros_power_state(param, val->s);
    blinker_dueros_print(param);
    cJSON_Delete(param);

    xTaskCreate(doLight, 
        "doLight",
        1024*2,
        ( void * )val->s,
        6,
        NULL);
} 